package com.ecr.hub.database.dao.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.ecr.hub.database.dao.IDaoDestination;
import com.ecr.hub.database.mapper.MapperDestination;
import com.ecr.hub.model.destination.Destination;
import com.ecr.hub.model.destination.DestinationRailTranscoder;
import com.ecr.hub.model.enumeration.HubObjectActive;

@Repository("daoDestination")
public class DaoDestinationImpl extends MapperDestination implements
		IDaoDestination {

	// Récupération de toutes les destinations (sauf destination cachée pour les
	// trains vides et les locomotives).
	private static final String REQ_SELECT_ALL = "SELECT * FROM hub_destination as dest "
			+ "WHERE dest.active="
			+ HubObjectActive.ACTIVE.getValue()
			+ " ORDER BY dest.id ASC";

	// Récupération d'une destination par son identifiant interne.
	private static final String REQ_SELECT_BY_ID = "SELECT * FROM hub_destination as dest WHERE dest.id=?";

	// Suppression d'une destination à partir de son identifiant interne.
	private static final String REQ_DELETE = "UPDATE hub_destination SET active="
			+ HubObjectActive.NOT_ACTIVE.getValue() + " WHERE id=?";

	// Insertion d'une nouvelle destination.
	private static final String REQ_INSERT = "INSERT INTO hub_destination (ext_id, "
			+ "hex_color, creation_date, label, comment, active, list_ext_id) VALUES (?,?,?,?,?,"
			+ HubObjectActive.ACTIVE.getValue() + ",?)";

	// Mise à jour d'une destination à partie de son identifiant interne.
	private static final String REQ_UPDATE = "UPDATE hub_destination SET ext_id=?, hex_color=?, "
			+ "label=?, comment=?, list_ext_id=? WHERE id=?";

	// Récupération de la dernière clé insérée pour une destination.
	private static final String REQ_SELECT_LAST_ID = "SELECT LAST_INSERT_ID() FROM hub_destination LIMIT 1";

	// Récupération de la correspondance entre les voies et les destinations.
	private static final String REQ_SELECT_DESTINATION_RAIL = "SELECT rail.id as rail_id, "
			+ "destination.id as destination_id, destination.ext_id, destination.list_ext_id "
			+ "FROM hub_rail as rail, hub_destination as destination "
			+ "WHERE rail.destination_id = destination.id";

	@Autowired
	JdbcTemplate jdbcTemplate;

	/**
	 * Récupération de la liste des destinations. Lecture de la table
	 * hub_destination, on ne prend que les enregistrements dont la colonne
	 * "active" est à "true".
	 */
	@Override
	public List<Destination> getAllList() throws DataAccessException {

		return jdbcTemplate.query(REQ_SELECT_ALL, mapperDestination);
	}

	/**
	 * Enregistrement d'une nouvellle destination, on enregistre dans la table
	 * hub_destination, on recherche la dernière clé enregistrée dans le
	 * processus courant.
	 */
	@Override
	public int create(Destination destination) throws DataAccessException {

		jdbcTemplate.update(REQ_INSERT, new Object[] { destination.getExtId(),
				destination.getHexColor(), destination.getCreationDate(),
				destination.getLabel(), destination.getComment(),
				destination.getLstExtId().trim() });

		return jdbcTemplate.queryForInt(REQ_SELECT_LAST_ID);
	}

	/**
	 * Mise à jour de la destination. Mise à jour de la ligne dans la table
	 * hub_destination.
	 */
	@Override
	public void update(Destination destination) throws DataAccessException {

		jdbcTemplate
				.update(REQ_UPDATE, new Object[] { destination.getExtId(),
						destination.getHexColor(), destination.getLabel(),
						destination.getComment(),
						destination.getLstExtId().trim(), destination.getId() });
	}

	/**
	 * Suppression de la ligne pour la destination dans la table
	 * hub_destination. On ne supprime en fait jamais les lignes, on se contente
	 * juste de passer l'indicateur "active" à "false", ceci afin de pouvoir
	 * conserver un historique sur l'ensemble des mouvements des wagons.
	 */
	@Override
	public void delete(Destination destination) throws DataAccessException {

		jdbcTemplate.update(REQ_DELETE, new Object[] { destination.getId() });
	}

	/**
	 * Récupération des informations destination à partir de l'identifiant
	 * interne de la destination.
	 */
	@Override
	public Destination getDestinationById(int id) throws DataAccessException {

		Destination destination = jdbcTemplate.queryForObject(REQ_SELECT_BY_ID,
				mapperDestination, new Object[] { id });
		return destination;
	}

	/**
	 * Suite à la problématique tardive ou plusieurs destinations peuvent aller
	 * sur une voie, on récupère la liste des correspondances entre chaque voie
	 * et chaque destination dans un objet spécifique qui permet par la suite de
	 * remapper toutes les destinations sur chaque voie.
	 */
	@Override
	public List<DestinationRailTranscoder> getListDestinationsRail()
			throws DataAccessException {

		List<DestinationRailTranscoder> lstTranscoders = jdbcTemplate.query(
				REQ_SELECT_DESTINATION_RAIL, mapperTranscoder);
		if (lstTranscoders.size() == 0)
			throw new EmptyResultDataAccessException(0);
		return lstTranscoders;
	}
}
